package com.team1160.scouting.panels;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import com.team1160.scouting.elements.NextButton;
import com.team1160.scouting.elements.NumberDropDownElement;
import com.team1160.scouting.elements.ScoutingElement;
import com.team1160.scouting.elements.SingleLineInputElement;
import com.team1160.scouting.elements.WeightingSliderElement;
import com.team1160.scouting.h2.DictWeightingTable;
import com.team1160.scouting.h2.MatchScoutingTable;
import com.team1160.scouting.h2.WeightingTable;
import com.team1160.scouting.resourcePackets.CardLayoutPacket;
import com.team1160.scouting.xml.XMLParser;
import java.awt.FlowLayout;

/**
 * This class is the panel that collects data in match scouting.<br><br><br>

 * @author Saketh Kasibatla
 */

//TODO saketh integrate sqlite and gui with SubmitButton
public class MatchPanel extends JPanel{

    /**
     * the layout packet containing the cardlayout for the next button.
     */
    CardLayoutPacket layout;

    /**
     * the toolbar displayed at the top.
     */
    JToolBar toolbar;

    /**
     * these panels are the left and right inputs (input and weighting)
     * and the button panels in those panels (inputbuttons and weightingbuttons)
     */
    JPanel inputPanel,weightingPanel,inputButtons,weightingButtons;
    /**
     * the panel under the toolbar.
     */
    JPanel bottomPanel;
    JScrollPane inputScroll,weightingScroll;

    JButton inputSubmit,inputClear,weightingSubmit,weightingClear;
    JLabel inputError,weightingError;

    SingleLineInputElement teamNum;
    ArrayList<ScoutingElement> input=new ArrayList<ScoutingElement>();
    ArrayList<WeightingSliderElement> weighting=new ArrayList<WeightingSliderElement>();

    XMLParser xml;

    MatchScoutingTable matchTable;
    WeightingTable weightingTable;
    DictWeightingTable dictWeightingTable;

    int[] IDs;
    String[] Names;


    public MatchPanel(CardLayoutPacket layout) throws Exception {
        this.layout = layout;
        this.toolbar=new JToolBar();
        xml=new XMLParser("."+File.separator+"data"+File.separator+"config.xml");
        this.setLayout(new BorderLayout());
        this.initToolbar();
        this.updateInput();
        this.initInputPanel();
        this.initWeightingPanel();
        
        bottomPanel=new JPanel();
        bottomPanel.setLayout(new BoxLayout(bottomPanel,BoxLayout.X_AXIS));

        bottomPanel.add(inputScroll);
        bottomPanel.add(weightingScroll);
        
        
        this.add(toolbar,BorderLayout.NORTH);
        this.add(bottomPanel,BorderLayout.CENTER);

    }

    private void initToolbar(){
        toolbar.setFloatable(false);
        toolbar.setLayout(new BorderLayout());
        toolbar.add(new NextButton(layout,"graph"),BorderLayout.EAST);
    }

    private void initInputPanel(){
        inputPanel=new JPanel();
        inputPanel.setBackground(Color.red);
        inputPanel.setLayout(new BoxLayout(inputPanel,BoxLayout.Y_AXIS));
        inputPanel.setAlignmentX(Component.LEFT_ALIGNMENT);

        inputButtons=new JPanel();
        inputButtons.setSize(200,50);

        inputSubmit=new JButton("Submit");
        inputSubmit.addActionListener(this.new MatchSubmit());

        inputClear=new JButton("Clear");
        inputClear.addActionListener(this.new MatchClear());

        inputError=new JLabel(".");
        inputError.setForeground(Color.red);
        inputError.setAlignmentX(Component.LEFT_ALIGNMENT);

        teamNum=new SingleLineInputElement("Team #:",SingleLineInputElement.INTEGER);
        teamNum.setAlignmentX(Component.LEFT_ALIGNMENT);
        inputPanel.add(teamNum);


        for(ScoutingElement e:input){
            inputPanel.add(e);
        }

        inputButtons.add(inputSubmit);
        inputButtons.add(inputClear);
        inputButtons.setAlignmentX(Component.LEFT_ALIGNMENT);

        inputPanel.add(Box.createVerticalStrut(200));
        inputPanel.add(inputError);
        inputPanel.add(inputButtons);

        inputScroll=new JScrollPane(inputPanel);
        inputScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        inputScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        //inputScroll.setSize(400, 500);
        
    }

    private void initWeightingPanel(){
        weightingPanel=new JPanel();
        weightingPanel.setBackground(Color.red);
        weightingPanel.setLayout(new BoxLayout(weightingPanel,BoxLayout.Y_AXIS));
        weightingPanel.setAlignmentX(Component.LEFT_ALIGNMENT);

        weightingButtons=new JPanel();
        weightingButtons.setSize(200,50);

        weightingSubmit=new JButton("Submit");
        weightingSubmit.addActionListener(this.new WeightingSubmit());

        weightingClear=new JButton("Clear");
        weightingClear.addActionListener(this.new WeightingClear());

        weightingError=new JLabel(".");
        weightingError.setForeground(Color.red);

        for(WeightingSliderElement e:weighting){
            weightingPanel.add(e);
        }

        weightingButtons.add(weightingSubmit);
        weightingButtons.add(weightingClear);

        weightingPanel.add(Box.createVerticalStrut(250));
        weightingPanel.add(weightingError);
        weightingPanel.add(weightingButtons);

        weightingScroll=new JScrollPane(weightingPanel);
        weightingScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        weightingScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        //weightingScroll.setSize(400, 500);
    }

    private void setupDB() throws Exception{
        matchTable=new MatchScoutingTable("."+File.separator+"data"+File.separator+"database"+File.separator+"database");

        weightingTable=new WeightingTable("."+File.separator+"data"+File.separator+"database"+File.separator+"database");

        dictWeightingTable=new DictWeightingTable("."+File.separator+"data"+File.separator+"database"+File.separator+"database");
        dictWeightingTable.reset();

        IDs=new int[weighting.size()];
        Names=new String[weighting.size()];
        for(int i=0;i<weighting.size();i++){
            IDs[i]=weighting.get(i).hashCode();
        }
        for(int i=0;i<weighting.size();i++){
            Names[i]=weighting.get(i).getText();
        }

        for(int i=0;i<IDs.length;i++){
            dictWeightingTable.insert(IDs[i], Names[i]);
        }
    }

    private void updateInput(){
        Element match = xml.getMatch();
        NodeList children = match.getElementsByTagName("field");
        for(int i=0;i<children.getLength();i++){
            Element e=(Element) children.item(i);
            String type=e.getAttribute("type");
            String name=e.getAttribute("name");
            if(type.equalsIgnoreCase("sIntInput")){
                SingleLineInputElement se=new SingleLineInputElement(name,SingleLineInputElement.INTEGER);

                if(!(e.hasAttribute("inWeight")&&e.getAttribute("inWeight").equals("false"))){
                    weighting.add(new WeightingSliderElement(name));
                    se.isWeighted=true;
                }else {
                    se.isWeighted=false;
                }
                se.setAlignmentX(Component.LEFT_ALIGNMENT);
                input.add(se);
            } else if(type.equalsIgnoreCase("numDropDown")){
                NumberDropDownElement ne=new NumberDropDownElement(name,
                        Integer.parseInt(e.getAttribute("bottom")),
                        Integer.parseInt(e.getAttribute("top")));

                if(!(e.hasAttribute("inWeight")&&e.getAttribute("inWeight").equals("false"))){
                    weighting.add(new WeightingSliderElement(name));
                    ne.isWeighted=true;
                }else{
                    ne.isWeighted=false;
                }
                ne.setAlignmentX(Component.LEFT_ALIGNMENT);
                input.add(ne);
            } else {
                throw new Error("wrong field type");
            }
        }
    }

    private void matchClear(){
        teamNum.clear();
        for(ScoutingElement se:input){
            se.clear();
        }
        setInputError(".");
    }

    private void weightingClear(){
        for(ScoutingElement se:weighting){
            se.clear();
        }
        setWeightingError(".");
    }

    private void setInputError(String s){
        this.inputError.setText(s);
    }

    private void setWeightingError(String s){
        this.weightingError.setText(s);
    }

    private class MatchClear implements ActionListener{

        public void actionPerformed(ActionEvent e) {
            matchClear();
        }

    }

    private class WeightingClear implements ActionListener{

        public void actionPerformed(ActionEvent e) {
            weightingClear();
        }

    }

    private class MatchSubmit implements ActionListener{

        public void actionPerformed(ActionEvent e) {
            boolean error=false;
            int[] dataset=new int[input.size()];
            for(int i=0;i<input.size();i++){
                
                if(input.get(i).getInput().equals("")){
                    setInputError("ERROR: one of the fields is empty");
                    error=true;
                    break;
                }else{
                    try{
                        dataset[i]=Integer.parseInt(input.get(i).getInput());
                    } catch (NumberFormatException nfe){
                        setInputError("ERROR: ALL fields must be integers");
                        error=true;
                        break;
                    }
                }
            }
            if(!error)
                    try {
                        for(int i=0;i<input.size();i++){
                            matchTable.insert(
                                    Integer.parseInt(teamNum.getInput()),
                                    input.get(i).hashCode(),
                                    dataset[i]);
                        }
                    } catch (NumberFormatException nfe){
                        setInputError("ERROR: ALL fields must be integers");
                        return;

                    }catch (Exception ex) {
                       ex.printStackTrace();
                    }
        }
    }

    private class WeightingSubmit implements ActionListener{
        public void actionPerformed(ActionEvent e) {
            boolean error=false;
            int[] values=new int[weighting.size()];
            for(int i=0;i<weighting.size();i++){
                if(weighting.get(i).getInput().equals("")){
                    setWeightingError("ERROR: one of the fields is empty");
                    error=true;
                    break;
                }else{
                    try{
                        values[i]=Integer.parseInt(weighting.get(i).getInput());
                    } catch (NumberFormatException nfe){
                        setWeightingError("ERROR: ALL fields must be integers");
                        error=true;
                        break;
                    }
                }
            }
            if(!error)
                try{
                    //TODO saketh finish fixing
                    weightingTable.reset();
                    for(int i=0;i<weighting.size();i++){
                        weightingTable.insert(
                                IDs[i],
                                values[i]);
                    }
                } catch (Exception ex){
                    ex.printStackTrace();
                }
        }

    }


}
